<script setup lang="ts">
import { onBeforeMount, onMounted, ref } from "vue";
import { Refresh, Search } from "@element-plus/icons-vue";
import {
  businessEntityAttributeFilterable,
  businessEntityAttributeVO,
  BusinessEntityAttributeVO,
  businessEntityPageList,
  remoteSearchOption
} from "@/api/lowCode";
import { BaseRequest, Option, ShowColumn } from "@/api/index";

const api = ref<string>("business_entity");

const baseRequest = ref<BaseRequest>({
  pageNo: 0,
  pageSize: 10,
  baseQueries: [
    {
      columnName: null,
      filterMode: null,
      values: []
    }
  ]
});

const filterableField = ref<Array<BusinessEntityAttributeVO>>([]);

const filterableFieldOption = ref<Map<string, Array<Option>>>(new Map());

const pageListDataSource = ref<Array<any>>([]);

const total = ref<number>(0);

const showColumns = ref<Array<ShowColumn>>([]);

const tableLoad = ref<boolean>(false);

const initFilterableField = async () => {
  const res = await businessEntityAttributeFilterable(api.value);
  if (res.success) {
    filterableField.value = res.data;
  }
};
const initShowColumns = async () => {
  const res = await businessEntityAttributeVO(api.value);
  if (res.success) {
    showColumns.value = res.data.map(item => {
      const showColumn: ShowColumn = {
        columnName: item.entityAttributeDescribe,
        columnApi: item.entityAttributeJavaField,
        width: 0
      };
      return showColumn;
    });
  }
};

const resetBaseRequest = () => {
  baseRequest.value.baseQueries.forEach(item => {
    item.values = [];
  });
};

const getPageListDataSource = async () => {
  tableLoad.value = true;
  const res = await businessEntityPageList(baseRequest.value);
  if (res.success) {
    pageListDataSource.value = res.data;
    total.value = parseInt(res.total);
  }
  tableLoad.value = false;
};

const reset = () => {
  resetBaseRequest();
  getPageListDataSource();
};

onBeforeMount(async () => {
  await initFilterableField();
  await initShowColumns();
});

onMounted(() => {
  getPageListDataSource();
});

const handleSizeChange = (val: number) => {
  baseRequest.value.pageSize = val;
  getPageListDataSource();
};
const handleCurrentChange = (val: number) => {
  baseRequest.value.pageNo = val;
  getPageListDataSource();
};
const isDisabled = (api: string, filterMode: string) => {
  const field = getFile(api);
  if (field) {
    if (field.referenceFlag || field.dictFlag) {
      if (
        filterMode === "=" ||
        filterMode === "!=" ||
        filterMode === "arrLike"
      ) {
        return false;
      }
      return true;
    }
  }
  return false;
};

const remoteMethod = async (query: string, api: string) => {
  const field = getFile(api);
  if (query) {
    const res = await remoteSearchOption(field.id, query);
    if (res.success) {
      filterableFieldOption.value.set(api, res.data);
    }
  } else {
    filterableFieldOption.value.set(api, []);
  }
};
const fieldChange = (api: string) => {
  // 获取字典项
  const field = getFile(api);
  if (field.dictFlag) {
    filterableFieldOption.value.set(api, []);
  }
};

const getFile = (api: string): BusinessEntityAttributeVO => {
  let field: BusinessEntityAttributeVO;
  filterableField.value.forEach(item => {
    if (item.entityAttributeJavaField === api) {
      field = item;
    }
  });
  return field;
};

const isDict = (api: string): boolean => {
  if (api) {
    const field = getFile(api);
    if (field.dictFlag) {
      return true;
    }
  }
  return false;
};
const isReference = (api: string): boolean => {
  if (api) {
    const field = getFile(api);
    if (field.referenceFlag) {
      return true;
    }
  }
  return false;
};
const isDate = (api: string): boolean => {
  if (api) {
    const field = getFile(api);
    if (
      field.entityAttributeType === "DATE" ||
      field.entityAttributeType === "DATETIME"
    ) {
      return true;
    }
  }
  return false;
};
</script>

<template>
  <el-row class="screen">
    <el-form
      :inline="true"
      class="demo-form-inline"
      label-position="left"
      label-width="100px"
    >
      <el-form-item
        v-for="item in baseRequest.baseQueries"
        :key="item.columnName"
      >
        <el-select
          v-model="item.columnName"
          @change="fieldChange"
          class="select_width"
        >
          <el-option
            v-for="field in filterableField"
            :key="field.id"
            :label="field.entityAttributeDescribe"
            :value="field.entityAttributeJavaField"
          />
        </el-select>
        <el-select v-model="item.filterMode">
          <el-option
            label="="
            value="="
            :disabled="isDisabled(item.columnName, '=')"
          />
          <el-option
            label=">"
            value=">"
            :disabled="isDisabled(item.columnName, '>')"
          />
          <el-option
            label="<"
            value="<"
            :disabled="isDisabled(item.columnName, '<')"
          />
          <el-option
            label=">="
            value=">="
            :disabled="isDisabled(item.columnName, '>=')"
          />
          <el-option
            label="<="
            value="<="
            :disabled="isDisabled(item.columnName, '<=')"
          />
          <el-option
            label="!="
            value="!="
            :disabled="isDisabled(item.columnName, '!=')"
          />
          <el-option
            label="介于"
            value="between"
            :disabled="isDisabled(item.columnName, '介于')"
          />
          <el-option
            label="包含"
            value="like"
            :disabled="isDisabled(item.columnName, '包含')"
          />
          <el-option
            label="不包含"
            value="notLike"
            :disabled="isDisabled(item.columnName, '不包含')"
          />
          <el-option
            label="引用包含"
            value="arrLike"
            :disabled="isDisabled(item.columnName, '引用包含')"
          />
        </el-select>
        <div v-if="item.filterMode == 'between'">
          <el-input v-model="item.values[0]" />
          -
          <el-input v-model="item.values[1]" />
        </div>
        <div v-else-if="isDict(item.columnName)">
          <el-select v-model="item.values" multiple>
            <el-option
              v-for="option in filterableFieldOption.get(item.columnName)"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </div>
        <div v-else-if="isReference(item.columnName)">
          <el-select
            v-model="item.values"
            multiple
            filterable
            remote
            reserve-keyword
            placeholder="请输入关键字"
            remote-show-suffix
            :remote-method="(query: string) => remoteMethod(query, item.columnName)"
          >
            <el-option
              v-for="option in filterableFieldOption.get(item.columnName)"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </div>
        <div v-else-if="isDate(item.columnName)">
          <el-date-picker
            v-model="item.values as [string, string]"
            type="datetimerange"
            value-format="YYYY-MM-DD HH:mm:ss"
            range-separator="To"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
          />
        </div>
        <div v-else>
          <el-input v-model="item.values[0]" />
        </div>
      </el-form-item>
    </el-form>
  </el-row>
  <el-row>
    <el-button :icon="Search" type="primary" style="width: 100px"
      >增加选项
    </el-button>
    <el-button
      :icon="Search"
      type="primary"
      @click="getPageListDataSource"
      style="width: 100px"
      >查询
    </el-button>
    <el-button :icon="Refresh" @click="reset" style="width: 100px"
      >重置
    </el-button>
  </el-row>
  <el-row class="action-bar">
    <el-button type="primary" plain size="small" style="width: 80px"
      >新建
    </el-button>
    <el-button type="primary" plain size="small" style="width: 80px"
      >导出
    </el-button>
    <el-button type="primary" plain size="small" style="width: 80px"
      >导入
    </el-button>
  </el-row>
  <el-row class="page-list">
    <el-table
      :data="pageListDataSource"
      style="width: 100%"
      v-loading="tableLoad"
    >
      <el-table-column
        v-for="item in showColumns"
        :key="item.columnApi"
        :prop="item.columnApi"
        :label="item.columnName"
        :width="item.width"
      >
        <template v-if="item.customHandle" #default="scope">
          {{ item.customHandle(scope.row) }}
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="操作" width="250">
        <template>
          <el-button link type="primary" size="small">编辑</el-button>
          <el-button link type="primary" size="small">详情</el-button>
          <el-button link type="primary" size="small">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-row>
  <el-row class="pagination">
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      background
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    />
  </el-row>
</template>

<style scoped>
.action-bar {
  margin-top: 10px;
}

.page-list {
  margin-top: 20px;
}

.pagination {
  float: right;
  margin-top: 20px;
}

.select_width {
  width: 150px;
}
</style>
